package raspberry_pi_app;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.apache.commons.lang3.StringUtils;
import org.apache.http.NameValuePair;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONException;
import org.json.JSONObject;

import bradz.media_server.raspberry_pi_app.R;
import android.app.ListActivity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.ListView;

public class ActivityMedia extends ListActivity{
	
	private ListView list_view;
	private ClassUberLogger logger;
	private ApplicationGlobalVars globals;
	private ClassNetworkHelper helper;
	private JSONObject media_json;
	private Context self;
	private ArrayAdapter<String> adapter;
	private directory_linked_list directory_tree;
	
	Handler mediaHandler = new Handler() {

  	    @Override
  	    public void handleMessage(Message msg) {
  	        switch (msg.what) {
	  	        case 0:
	  	        	logger.info("Received Media Data!");
	  	        	logger.info(String.valueOf(msg.obj));
					try {
						media_json = new JSONObject(String.valueOf(msg.obj));
						logger.info(media_json.toString());
						create_link("/mnt");
						format_list("");
					} catch (JSONException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					set_click_actions();
	  	            break;
	  	        default:
	  	            break;
  	        }
  	    }
  	};
	
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
	    setContentView(R.layout.activity_media);
	    logger = new ClassUberLogger("ActivityMain");
	    globals = ((ApplicationGlobalVars) this.getApplication());
	    helper = new ClassNetworkHelper(this,globals);
	    media_json = new JSONObject();
	    list_view = getListView();
	    self = this;
	    adapter = new ArrayAdapter<String>(self,R.layout.list);
	    pull_list();
	}
	
	public void pull_list(){
		helper.get_message("set_media/",mediaHandler);
	}
	
	public void set_click_actions(){
		list_view.setOnItemClickListener(new AdapterView.OnItemClickListener() {
            public void onItemClick(AdapterView<?> parent, final View view, int position, long id) {            	
            	logger.info("Position: " +  position);
            	logger.info("Key: " +  adapter.getItem(position));
            	if(media_json.has(adapter.getItem(position)) || adapter.getItem(position).equals("..")){
            		logger.info("Key in json");
            		format_list(adapter.getItem(position));
            	}else{
            		//The click is on a media asset. Attempt to play it...
            		
            		logger.info("Sending: " + directory_tree.path + "/" + adapter.getItem(position));
            		
            		List<NameValuePair> pairs = new ArrayList<NameValuePair>();
            		pairs.add(new BasicNameValuePair("message", directory_tree.path + "/" + adapter.getItem(position)));
            		pairs.add(new BasicNameValuePair("payload", globals.get_developer_payload()));
            		helper.send_message(pairs,"mymovies_media/");
            	}
            }
        });
	}
	
	public void format_list(String json_key){
		ArrayList<String> files = new ArrayList<String>();
		ArrayList<String> folders = new ArrayList<String>();
		
		if(json_key.isEmpty() || json_key.equals("..")){
			
			if(directory_tree.parent != null){
				directory_tree = directory_tree.parent;
				if(directory_tree.parent != null){
					json_key = directory_tree.path;
				}else{
					json_key = "";
				}
			}else{
				json_key = "";
			}
			for(directory_linked_list child: directory_tree.children){
				folders.add(child.path);
				Collections.sort(folders);
			}
		}else{
			for(directory_linked_list item: directory_tree.children){
				if(item.path.equals(json_key)){
					directory_tree = item;
					for(directory_linked_list child: directory_tree.children){
						folders.add(child.path);
					}
					Collections.sort(folders);
					break;
				}
			}
		}
		
		folders.add(0, "..");
		files = format_json_array(json_key);
		Collections.sort(files);
		folders.addAll(files);
		
	    adapter = new ArrayAdapter<String>(self,R.layout.list, folders);
	    setListAdapter(adapter);
	    adapter.notifyDataSetChanged();
	}
	
	public ArrayList<String> format_json_array(String json_key){
		ArrayList<String> return_array = new ArrayList<String>();
		if(media_json.has(json_key)){
			try {
				return_array = new ArrayList<String>(Arrays.asList(media_json.get(json_key).toString().replace("[","").replace("]", "").split("\",\"")));
				for(int i = 0; i < return_array.size(); i++){
					return_array.set(i, return_array.get(i).replace("\"", "").replace(",",""));
				}
			}catch(Exception e){
				e.printStackTrace();
			}
		}
		return return_array;
	}
	
	public void create_link(String root){
		
		ArrayList<String> keys = new ArrayList<String>();
		
		Iterator<String> key_iterator = media_json.keys();
		while (key_iterator.hasNext()){
			String next_key = key_iterator.next();
			if(!next_key.equals(root)){
				logger.info("Adding: " + next_key);
				keys.add(next_key);
			}
	    }
		
		directory_tree = new directory_linked_list(null,root);
		create_list(directory_tree,keys);
	}
	
	public void create_list(directory_linked_list parent, ArrayList <String> directories){
		
		ArrayList<String> not_on_this_level = new ArrayList<String>();
		for(String directory : directories){
			int levels_away = StringUtils.countMatches(directory.replace(parent.path, ""), "/");
			if(levels_away <= 1){
				//We are one level away from the parent here
				parent.children.add(new directory_linked_list(parent,directory));
			}else if(directory.contains(parent.path)){
				not_on_this_level.add(directory);
			}
		}
		for(directory_linked_list child : parent.children){
			create_list(child,not_on_this_level);
		}
	}
	
	class directory_linked_list{
		public directory_linked_list parent;
		public ArrayList<directory_linked_list> children;
		public String path;
		directory_linked_list(directory_linked_list parent, String path){
			this.parent = parent;
			this.path = path;
			this.children = new ArrayList<directory_linked_list>();
		}
	}
}
